package com.ihr360.rest.serializer.fastjson;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.ihr360.commons.model.annotation.EnumData;
import org.apache.commons.beanutils.MethodUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * ValueFilter for Enum
 *
 * @author david.wei
 */
public class EnumDataFilter implements Ihr360SerializeFilter, ValueFilter {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private final Map<Class<?>, Method> valueMethods = new HashMap<>();

    @Override
    public Set<Class<?>> getSupportTypes() {
        return this.valueMethods.keySet();
    }

    @Override
    public Object process(Object object, String name, Object value) {
        if (value == null) {
            return value;
        }

        Class clazz = value.getClass();
        if (clazz.isArray()) {
            JSONArray result = new JSONArray();
            Object[] objects = (Object[]) value;
            int i = 0;
            for (; i < objects.length; i++) {
                Object model = getModel(objects[i], objects[i].getClass());
                result.add(model);
            }
            return result;
        }
        return getModel(value, clazz);
    }

    private Object getModel(Object value, Class clazz) {
        if (!clazz.isEnum() || clazz.getAnnotation(EnumData.class) == null) {
            return value;
        }

        Method m = MethodUtils.getAccessibleMethod(clazz, "getTitle", new Class[0]);
        if (null != m) {
            try {
                Object e = m.invoke(value);
                JSONObject result = new JSONObject();
                result.put("id", ((Enum) value).name());
                result.put("title", e);
                return result;
            } catch (Exception var7) {
                this.logger.info("process " + value.getClass() + " value of method " + m.getName() + " failure", var7);
            }
        }
        return value;
    }
}